package org.beetl.json.node;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.beetl.json.ActionComparator;
import org.beetl.json.ActionReturn;
import org.beetl.json.JsonTool;
import org.beetl.json.JsonWriter;
import org.beetl.json.Location;
import org.beetl.json.OutputNode;
import org.beetl.json.action.IInstanceAction;
import org.beetl.json.action.IValueAction;
import org.beetl.json.loc.ClassTypeLocation;
import org.beetl.json.loc.ThisLocation;
import org.beetl.json.util.JsonUtil;

public class PojoNode extends OutputNode {

	Class c;
	List<PojoAttributeNode> attrs = new ArrayList<PojoAttributeNode>();
	boolean cycleCheck = true;
	
	public PojoNode(Class c) {
		this.c = c;
	}

	@Override
	public void render(Object obj, JsonWriter w) throws IOException {
		
		if(valueActions.size()!=0){			
			for(IValueAction valueAction:valueActions){
				ActionReturn ar = valueAction.doit(obj, this,w);	
				obj = ar.value;			
				if(ar.process==ActionReturn.CONTINUE){
					break ;
				}else if(ar.process==ActionReturn.RETURN){
					return ;
				}
			}								
		}	
		boolean rember = w.isRemberObject();
		if(rember){
			w.addObject(obj);
			w.setRemberObject(false);
		}
		
		w.writeScopeChar('{');
		Iterator<PojoAttributeNode> it = attrs.iterator();
		if(!it.hasNext()){
			w.writeScopeChar('}');
			
		}else{
			
			while(true){
				PojoAttributeNode node = it.next();
				node.render(obj, w);
					
				
				if(!it.hasNext()){
					w.writeScopeChar('}');
					break;
				}
				w.writeComma();		
				
				
			}
		}
		if(rember){
			w.removeLast();
			
		}
	
		return ;
	

	}

	@Override
	public void setActionByLocation(List<Location> list) {
		Method[] ms = c.getMethods();
		for (Method m : ms) {
			if (JsonUtil.isGetterMethod(m)) {
				// @todo: list map,class,etc node
				if (!JsonTool.isStopParse(m.getDeclaringClass().getName())) {
					
					PojoAttributeNode node = new PojoAttributeNode(c,m);	
					node.setActionByLocation(list);
					if(!node.isIgnore()){
						attrs.add(node);
					}
				}

			}
		}
		
		for(Location l:list){
			if(l instanceof ClassTypeLocation){
				if(((ClassTypeLocation)l).match(this, c, null)){
					this.valueActions.add((IValueAction)l.getAction());
				}
			}
		}
		
		
		
		if(JsonTool.orderAttribute){			
			Collections.sort(attrs,JsonTool.orderAttributeComparator);
		}
		
		

		{
			// 查找是否有作用到instace的Action
			List<IInstanceAction> classActions = new ArrayList<IInstanceAction>(	);
			for (Location loc : list) {
				if (loc instanceof ThisLocation) {
					classActions.add((IInstanceAction) loc.getAction());
				}
			}
			
			Collections.sort(classActions,new ActionComparator());
			// 预先处理
			if (classActions.size() != 0) {
				for (IInstanceAction ca : classActions) {
					ActionReturn ar = ca.doit(this);
					if (ar.process==ActionReturn.CONTINUE) {
						attrs = (List<PojoAttributeNode>) ar.value;
					} else {
						break;
					}

				}

			}
			
		}
		
	}

	public List<PojoAttributeNode> getAttrs() {
		return attrs;
	}

	public boolean isCycleCheck() {
		return cycleCheck;
	}

	public void setCycleCheck(boolean cycleCheck) {
		this.cycleCheck = cycleCheck;
	}

	
}
